use std::sync::Arc;
use tonic::transport::Server;
use tracing::{info, error};

use crate::grpc::service::{NacosGrpcService, ClusterService, DataSyncService};
use crate::proto::nacos_service_server::NacosServiceServer;

/// gRPC服务器管理器
pub struct GrpcServer {
    /// 服务地址
    address: String,
    /// 服务实例
    service: Arc<NacosGrpcService>,
    /// 服务器句柄
    server_handle: Option<tokio::task::JoinHandle<()>>,
}

impl GrpcServer {
    /// 创建新的gRPC服务器
    pub fn new(
        address: String,
        cluster_service: Arc<dyn ClusterService>,
        data_sync_service: Arc<dyn DataSyncService>,
    ) -> Self {
        let service = Arc::new(NacosGrpcService::new(cluster_service, data_sync_service));
        Self {
            address,
            service,
            server_handle: None,
        }
    }

    /// 启动服务器
    pub async fn start(&mut self
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let addr = self.address.parse()?;
        let service = self.service.clone();

        info!("🚀 启动gRPC服务器: {}", self.address);

        let server = Server::builder()
            .add_service(NacosServiceServer::from_arc(service))
            .serve(addr);

        let handle = tokio::spawn(async move {
            if let Err(e) = server.await {
                error!("❌ gRPC服务器错误: {}", e);
            }
        });

        self.server_handle = Some(handle);
        info!("✅ gRPC服务器已启动: {}", self.address);

        Ok(())
    }

    /// 停止服务器
    pub async fn stop(&mut self
    ) {
        if let Some(handle) = self.server_handle.take() {
            handle.abort();
            info!("🛑 gRPC服务器已停止");
        }
    }

    /// 获取服务器地址
    pub fn address(&self) -> &str {
        &self.address
    }

    /// 检查服务器是否在运行
    pub fn is_running(&self) -> bool {
        self.server_handle.is_some()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::Duration;
    use async_trait::async_trait;

    struct MockClusterService;
    struct MockDataSyncService;

    #[async_trait]
    impl ClusterService for MockClusterService {
        async fn get_cluster_info(&self) -> Result<String, tonic::Status> {
            Ok("{\"nodes\":[]}".to_string())
        }
        async fn add_node_from_info(&self, _node_info: String) -> Result<(), tonic::Status> {
            Ok(())
        }
        async fn remove_node(&self, _node_id: &str) -> Result<(), tonic::Status> {
            Ok(())
        }
        async fn is_healthy(&self) -> Result<bool, tonic::Status> {
            Ok(true)
        }
    }

    #[async_trait]
    impl DataSyncService for MockDataSyncService {
        async fn handle_sync_message(
            &self,
            _sync_type: String,
            _from_node: String,
            _data: String,
            _version: u64,
            _timestamp: u64,
        ) -> Result<String, tonic::Status> {
            Ok("synced".to_string())
        }
    }

    #[tokio::test]
    async fn test_grpc_server_start_stop() {
        let cluster_service = Arc::new(MockClusterService);
        let data_sync_service = Arc::new(MockDataSyncService);
        
        let mut server = GrpcServer::new(
            "127.0.0.1:0".to_string(), 
            cluster_service, 
            data_sync_service
        );

        // 启动服务器
        server.start().await.unwrap();
        assert!(server.is_running());

        // 停止服务器
        server.stop().await;
        assert!(!server.is_running());
    }

    #[tokio::test]
    async fn test_grpc_server_with_random_port() {
        let cluster_service = Arc::new(MockClusterService);
        let data_sync_service = Arc::new(MockDataSyncService);
        
        let mut server = GrpcServer::new(
            "127.0.0.1:0".to_string(), 
            cluster_service, 
            data_sync_service
        );

        // 启动服务器
        server.start().await.unwrap();
        
        // 等待服务器启动
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        // 停止服务器
        server.stop().await;
    }
}